#include "stdafx.h"
#include <stdlib.h>
#include <io.h>
#include "ckDataProductManager.h"
#include "ckDataProductInfo.h"
#include "ckCommand.h"
#include "ckConnection.h"
#include "ckSchema.h"
#include "ckRunTime.h"

#include "ckSchemaReader.h"


namespace ck
{

	DataProductManager::DataProductManager()
	{
		m_pConnection = NULL;
	}


	DataProductManager::~DataProductManager()
	{
		std::vector<DataProductInfo*>::iterator iter1;
		for (iter1 = m_products.begin(); iter1 != m_products.end(); iter1++)
		{
			(*iter1)->Release();
		}
		m_products.clear();

		data::Schema* pSchema = NULL;
		std::vector<data::Schema*>::iterator iter2;
		for (iter2 = m_schemas.begin(); iter2 != m_schemas.end(); iter2++)
		{
			pSchema = *iter2;
			if (pSchema)
			{
				pSchema->Release();
			}
		}
		m_schemas.clear();
		
	}

	DataProductManager*	DataProductManager::GetInstance()
	{
		static DataProductManager g_productManager;
		return &g_productManager;
	}

	RESULTCODE DataProductManager::Load()
	{
		if (m_products.size() > 0)
		{
			return RC_SUCCESS;
		}

		const char* szSQL = "SELECT ID,CK_CODE,CK_NAME,CK_DATATYPE,CK_DESCRIPTION FROM CK_PRODUCT";

		DataProductInfo* pProduct = NULL;

		Command* pCommand = m_pConnection->CreateCommand();
		ADODB::_RecordsetPtr pRecordset = pCommand->ExecuteQuery(szSQL);
		if (pRecordset)
		{
			while (!pRecordset->adoEOF)
			{
				z_uint32 id = (z_uint32)pRecordset->GetCollect("ID");
				z_uint32 code = (z_uint32)pRecordset->GetCollect("CK_CODE");
				_bstr_t bstrName = (_bstr_t)pRecordset->GetCollect("CK_NAME");
				_bstr_t bstrType = (_bstr_t)pRecordset->GetCollect("CK_DATATYPE");
				_bstr_t bstrDesc = (_bstr_t)pRecordset->GetCollect("CK_DESCRIPTION");

				pProduct = new DataProductInfo();
				pProduct->SetID(id);
				pProduct->SetCode(code);
				pProduct->SetName((const char*)bstrName);
				pProduct->SetTypeAsString((const char*)bstrType);
				pProduct->SetDescription((const char*)bstrDesc);
				m_products.push_back(pProduct);
				
				pRecordset->MoveNext();
			}
		}

		pCommand->Release();

		m_schemas.resize(m_products.size());
		for (int i = 0; i < m_schemas.size(); i++)
		{
			m_schemas[i] = NULL;
		}

		return RC_SUCCESS;
	}

	void DataProductManager::SetConnection(Connection* pConnection)
	{
		m_pConnection = pConnection;
	}

	z_uint32 DataProductManager::GetCount()
	{
		return m_products.size();
	}

	DataProductInfo* DataProductManager::GetDataProduct(z_uint32 i)
	{
		if (i >= m_products.size())
		{
			return NULL;
		}
		return m_products[i];
	}

	data::Schema* DataProductManager::GetSchema(z_uint32 i)
	{
		if (i >= m_schemas.size())
		{
			return NULL;
		}

		data::Schema* pSchema = NULL;
		pSchema = m_schemas[i];

		if (pSchema == NULL)
		{
			DataProductInfo* pProduct = m_products[i];
			ckDataProductType type = (ckDataProductType)pProduct->GetCode();
			switch(type)
			{
			case ckDptLandsat05:
			case ckDptLandsat08:
			{
				ck::RunTime* pRunTime = ck::RunTime::GetInstance();
				const char* szConfPath = pRunTime->GetConfigHome();
				char szTemplatePath[Z_PATH_MAX];
				memset(szTemplatePath, 0, Z_PATH_MAX);
				_makepath(szTemplatePath, NULL, szConfPath, "Landsat5MetaConstraint", "xml");

				if (_access(szTemplatePath, 4) != 0)
				{
					return NULL;
				}

				ck::data::SchemaReader reader;
				pSchema = reader.Read(szTemplatePath);
			}
				break;
			}
		}

		m_schemas[i] = pSchema;
		return pSchema;
	}

	data::Schema* DataProductManager::GetSchema(ckDataProductType type)
	{
		data::Schema* pSchema = NULL;

		DataProductInfo* pProduct = NULL;
		std::vector<DataProductInfo*>::iterator iter;
		for (iter = m_products.begin(); iter != m_products.end(); iter++)
		{
			pProduct = *iter;
			if (pProduct->GetType() == type)
			{
				z_uint32 idx = iter - m_products.begin();
				pSchema = GetSchema(idx);
			}
		}

		return pSchema;
	}
}
